﻿using System;
using System.Collections.Generic;
using System.Text;
using LispInterpretor.HelperClasses;

namespace LispInterpretor.InBuiltProcedures.ListOperations
{
    public class Rest : Procedure
    {
        public override object Apply(params object[] args)
        {
            Check.IsTrue(args.Length == 1, "The procedure \"rest\" only has a single argument.");

            Check.IsTrue(args[0] is IList<object>, "The procedure \"rest\" requires a list passed to it as an argument.");

            IList<object> items = args[0] as IList<object>;

            Check.IsTrue(items.Count > 0, "The procedure \"rest\" can not be applied to an empty list.");

            object[] sourceArray = ConvertListToArray(items);

            return CopyArray(sourceArray, 1);
        }

        private static object[] CopyArray(object[] sourceArray, int startIndex)
        {
            object[] targetArray = new object[sourceArray.Length - 1];
            Array.Copy(sourceArray, startIndex, targetArray, 0, sourceArray.Length - startIndex);
            return targetArray;
        }

        private static object[] ConvertListToArray(IList<object> items)
        {
            var sourceArray = new object[items.Count];

            items.CopyTo(sourceArray, 0);

            return sourceArray;
        }
    }
}
